
include Gosu
include Button

class ControlsMenu < UIMenuDelegate
BTN_STRINGS = { # what a mess.
  KbDown => "down", KbUp => "up", KbLeft => "left", KbRight => "right",
  KbLeftShift => "left shift", KbRightShift => "right shift",
  KbLeftControl => "left ctrl", KbRightControl => "right ctrl",
  KbLeftAlt => "left alt", KbRightAlt => "right alt",
  KbBackspace => "backspace", KbTab => "tab", KbSpace => "Spacebar",
  KbInsert => "insert", KbHome => "home", KbEnter => "enter",
  KbReturn => "return", MsLeft => "mouse left", 
  MsRight => "mouse right", MsWheelDown => "mouse wheel down",
  MsWheelUp => "Mouse wheel up", KbPageDown => "page down",
  KbPageUp => "page up",
  KbA => "A", KbB => "B", KbC => "C", KbD => "D", KbE => "E",
  KbF => "F", KbG => "G", KbH => "H", KbI => "I", KbJ => "J",
  KbK => "K", KbL => "L", KbM => "M", KbN => "N", KbO => "O",
  KbP => "P", KbQ => "Q", KbR => "R", KbS => "S", KbT => "T", 
  KbU => "U", KbV => "V", KbW => "W", KbX => "X", KbY => "Y",
  KbZ => "Z", Kb1 => "1", Kb2 => "2", Kb3 => "3", Kb4 => "4",
  Kb5 => "5", Kb6 => "6", Kb7 => "7", Kb8 => "8", Kb9 => "9", 
  Kb0 => "0", KbNumpad0 => "numpad 0", KbNumpad1 => "numpad 1", 
  KbNumpad2 => "numpad 2", KbNumpad3 => "numpad 3", 
  KbNumpad4 => "numpad 4", KbNumpad5 => "numpad 5", 
  KbNumpad6 => "numpad 6", KbNumpad7 => "numpad 7", 
  KbNumpad8 => "numpad 8", KbNumpad9 => "numpad 9"
} # I copy-pasted most of it from DD, though, so no big hassle.

  def initialize(window, screen)
    super(window, screen)
    @section_number = 1 # one column in this menu to start off
    @section_width = 225
    @margin = 0
    @pos_x = 100
    @pos_y = 100
    @set_control_mode = false

    @target_player_index = 0
    @player_colors = [0xff0000ff, 0xffff0000, 0xff00ff00, 0xff990099]
    @player_buttons = []
    4.times {|i| @player_buttons << UIButton.new(window, self, 
                                        "Player #{i + 1}", :goto_controls) }
    @player_buttons.each_with_index do |btn, i| 
      btn.static_color = @player_colors[i] 
      btn.hover_color = @player_colors[i] - 0x77000000
    end

    @control_buttons = []
    control_names = ["Accelerate", "Reverse", "Turn Left", "Turn Right", "Shoot"]
    control_names.each do |btn|
      @control_buttons << UIButton.new(window, self, btn, :set_control)
    end
    @selected_color = 0xffffff00
    @selected_control = @control_buttons[0] # just as a default

    @id_boxes = []
    5.times { @id_boxes << UITextItem.new(@window, self, "") }
    # these are used to display current configurations
    
    @text_box = UITextItem.new(@window, self, "")
    @text_box.set_text_height(15)
    # used to display the "press a key" alert

    @menu.build_menu
  end

  def update
    return if @set_control_mode 
    # input button.
    super
  end

  def draw
    super
    @control_buttons.each do |btn| 
      btn.static_color = @player_colors[@target_player_index]
      btn.hover_color = @player_colors[@target_player_index] - 0x77000000
    end
  end

  def button_down(id)
    if @set_control_mode
      control = @selected_control.text
      @window.game_controls[@target_player_index][control] = id
      # EX: @window.game_controls[1]["Accelerate"] = KbUp # red accelerates on 'up'
      @set_control_mode = false
      @section_number = 3
      reset_id_boxes
      @menu.build_menu
    else
      super
    end
  end

  def menuItemsInSection(section_index)
    case section_index
    when 0
      return @player_buttons.size + 1 # +1 for the "back" button
    when 1
      return @control_buttons.size
    when 2
      return @id_boxes.size
    when 3
      return @control_buttons.index(@selected_control) + 1
    end
  end

  def menuItemForIndex(row_index, section_index)
    case section_index
    when 0
      if row_index != @player_buttons.size
        return @player_buttons[row_index] 
      else
        return UIButton.new(@window, self, "Back", :goto_back)
      end
    when 1
      return @control_buttons[row_index]
    when 2
      return @id_boxes[row_index]
    when 3
      if row_index == @control_buttons.index(@selected_control)
        action = @selected_control.text
        @text_box.text = "Press a button for \"#{action}\""
        return @text_box
      else
        return UIMenuItem.new(@window, self, "") # empty place-holder
      end
    end
  end

  def set_control(sender)
    @selected_control = sender
    @selected_control.hover_color = @selected_color
    @section_number = 4
    @set_control_mode = true
    @menu.build_menu
    @menu.update # my lazy way of making the text appear properly 
                  # before the set-control update freeze
  end

  def goto_controls(sender)
    @target_player_index = /\d/.match(sender.text).to_s.to_i - 1
    # returns player num (1..4)
    reset_id_boxes # reset the text in the boxes
    @section_number = 3
    @menu.build_menu
  end

  def reset_id_boxes
    @id_boxes.each_with_index do |box, i|
      id = @window.game_controls[@target_player_index][@control_buttons[i].text] 
      # quite a mouthful. Returns the button ID for the action
      text = BTN_STRINGS[id]
      text = id.to_s if !text
      box.text = text
    end
  end

  def goto_back(sender)
    GameControls.save_inputs(@window.game_controls)
    @screen.pop_menu
  end

  def menu_will_disappear
    goto_back(:kill)
    super
  end

end
